import { _decorator, Component, Node, TextAsset } from 'cc';
import EventMgr from './EventMgr';
import { plog } from '../Utils/Tools';
const { ccclass, property } = _decorator;

export enum State {
    Closed = 0, // 断开连接
    Linking = 1, // 正在连接
    Linked = 2, // 已经连接;
    // OnLogin = 3 //已经登陆
};

const MaxCountConnect = 3

@ccclass('NetMgr')
export default class NetMgr extends Component {
    public static Instance: NetMgr = null;

    // private url: string = "ws://127.0.0.1:22000";
    private url: string = "ws://30315aeb.r9.cpolar.top";
    private state: State = State.Closed;
    private sock: WebSocket = null;

    private countConnect = 0;


    onLoad() {
        if (NetMgr.Instance === null) {
            NetMgr.Instance = this;
        }
        else {
            this.destroy();
            return;
        }
        this.SetState(State.Closed)
    }

    //连接成功
    _on_opened(event) {
        plog("connect to server: " + this.url + " sucess!");
        // EventMgr.Instance.dispatch_event("net_register", null);
        this.SetState(State.Linked)
        EventMgr.Instance.dispatch_event("net_connect", null);
    }

    //收到数据
    _on_recv_data(event) {
        plog("---------- link recv", event)
        EventMgr.Instance.dispatch_event("net_message", event.data);
    }

    close_socket() {
        if (this.GetState() != State.Closed) {
            this.SetState(State.Closed)
        } else {
            return
        }
        if (this.sock !== null) {
            if (this.countConnect < MaxCountConnect) {
                setTimeout(() => {
                    this.connect_to_server()
                }, 200);
            } else {
                this.countConnect = 0;
                EventMgr.Instance.dispatch_event("net_disconnect", null);
            }
        }
    }
    //服务器关闭
    _on_socket_close(event) {
        plog("---------- link close", event)
        this.close_socket();
    }
    //连接失败
    _on_socket_err(event) {
        plog("---------- link err", event)
        this.close_socket();
    }

    // 发起连接;
    connect_to_server() {
        plog("connect_to_server in..")
        if (this.GetState() !== State.Closed) {
            return;
        }
        plog("=======start link:", this.url)
        this.SetState(State.Linking)

        EventMgr.Instance.dispatch_event("net_connecting", null);

        this.sock = new WebSocket(this.url); // H5标准，底层做好了;
        this.sock.binaryType = "arraybuffer";

        this.sock.onopen = this._on_opened.bind(this);
        this.sock.onmessage = this._on_recv_data.bind(this);
        this.sock.onclose = this._on_socket_close.bind(this);
        this.sock.onerror = this._on_socket_err.bind(this);
        this.countConnect++
        plog("connect_to_server out..")
    }

    // createSocket() {
    //     this.state = State.Connecting;
    //     EventMgr.Instance.dispatch_event("net_connecting", null);
    //     this.sock = new WebSocket(this.url); // H5标准，底层做好了;
    //     this.sock.binaryType = "arraybuffer";
    //     this.sock.onopen = this._on_opened.bind(this);
    //     this.sock.onmessage = this._on_recv_data.bind(this);
    //     this.sock.onclose = this._on_socket_close.bind(this);
    //     this.sock.onerror = this._on_socket_err.bind(this);
    //     this.countConnect++
    // }



    // update(dt: number) {
    // start() {
    //     if (this.state !== State.Disconnected) {
    //         return;
    //     }

    //     this.connect_to_server();
    // }

    //主动断连
    public CloseConnect() {
        if (this.GetState() !== State.Closed) {
            this.SetState(State.Closed);//先设置好了状态，就不会进入断连回调了
            if (this.sock !== null) {//主动断连
                this.sock.close();
                this.sock = null;
            }
        }
    }

    // public ConnectSucceed() {
    //     this.state = State.Connected;
    //     EventMgr.Instance.dispatch_event("net_connect", null);
    // }

    public SetState(st: State) {
        this.state = st
    }
    public GetState(): State {
        return this.state
    }

    send_data(data_arraybuf) {
        plog("send------ ", data_arraybuf, this.state, this.sock)
        if (this.sock && this.GetState() == State.Linked) {
            this.sock.send(data_arraybuf);
        }
    }

}
